<?php
/**
 * 消费者
 */

namespace Xtsb\Cims\MQ\Queue;

use Xtsb\Cims\Route\Route;
use think\facade\Log;
use think\queue\Job;

class Consumer
{
  /**
   * 启动：php think queue:listen --queue xtsbJobQueue
   * @param Job $job
   * @param $data
   * @return void
   */
  public function fire(Job $job, $data)
  {
    $jobData = json_decode($data, true);

    $tag = $jobData['tag'] ?? null;
    $jobData = $jobData['data'] ?? null;
    Log::channel('queue')->info('队列开始 | ' . $tag . '：{data}', ['data' => $data]);

    // 有些消息在到达消费者时,可能已经不再需要执行了

    $isJobStillNeedToBeDone = $this->checkDatabaseToSeeIfJobNeedToBeDone($data);

    if (!$isJobStillNeedToBeDone) {

      $job->delete();

      Log::channel('queue')->info('队列废弃 | ' . $tag . '：{data}', ['data' => $data]);

      return;

    }


    $isJobDone = $this->doJob($tag, $jobData);
    $job->delete();
    if ($isJobDone) {

      // 如果任务执行成功， 记得删除任务

      $job->delete();

      Log::channel('queue')->info('队列已完成 | ' . $tag . '：{data}', ['data' => $data]);

    } else {
      Log::channel('queue')->info('队列执行失败 | ' . $tag . '：{data}', ['data' => json_encode($job)]);

      if ($job->attempts() > 3) {

        //通过这个方法可以检查这个任务已经重试了几次了

        Log::channel('queue')->info('队列执行操作3次 | ' . $tag . '：{data}', ['data' => $data]);


        $job->delete();


        // 也可以重新发布这个任务

        //print("<info>Hello Job will be availabe again after 2s."."</info>\n");

        //$job->release(2); //$delay为延迟时间，表示该任务延迟2秒后再执行

      }

    }

  }


  /**
   * 有些消息在到达消费者时,可能已经不再需要执行了
   * @param array|mixed $data 发布任务时自定义的数据
   * @return boolean                 任务执行的结果
   */

  private function checkDatabaseToSeeIfJobNeedToBeDone($data)
  {

    return true;

  }


  /**
   * 根据消息中的数据进行实际的业务处理...
   */

  private function doJob($tag, $data)
  {

//    print("<info>Hello Job Started. job Data is: " . var_export($data, true) . "</info> \n");
//
//    print("<info>Hello Job is Fired at " . date('Y-m-d H:i:s') . "</info> \n");
//
//    print("<info>Hello Job is Done!" . "</info> \n");


    try {
      $queueClass = 'app\\Queue\\' . Route::getController($tag);

      $queue = new $queueClass();

      $queue->boot($data);

      return true;

    } catch (\Exception $exception) {
      Log::channel('queue')->info('doJob：队列执行异常 | ' . $tag . '：{data}', ['data' => $exception->getMessage() . ' | ' . $exception->getFile() . ' | ' . $exception->getLine()]);

      return false;
    }
//    switch ($tag) {
//      case 'mail':
//        //发送邮件
//        break;
//      case 'file':
//        //发送邮件
//        echo 'file';
//        break;
//      case 'excel':
//        //发送邮件
//        break;
//      default:
//        break;
//    }


  }


  public function failed($data)
  {


    // ...任务达到最大重试次数后，失败了

  }


}